module shader.litshadersky;

import scene.scene;
import scene.ray;
import scene.intersection;
import shader.environment;
import shader.abstractshader;
import std.math;
import utils.color;
import utils.vector3;
import utils.mt19937ar;

class LitShaderSky: AbstractShader {
    const float SHADE_EPSILON = 0.01f;
    const int SAMPLE_COUNT = 100;

    private Environment mEnvironment;

    public void getColor(inout Ray ray, inout Intersection inters,
        inout RGBColor col)
    {
        Vector3f x = ray.start+ray.dir*inters.t;    //point on surface
        Vector3f n = mScene.getNormal(inters);      //surface normal
        RGBColor litCol;
        Intersection ints;
        Ray secRay;
        for (int i = 0; i < SAMPLE_COUNT; i++) {
            float phi = 2.0f*PI*genrand_real1();
            float theta = PI_2*genrand_real1();
            secRay = Ray(x+n*SHADE_EPSILON,Vector3f.fromSpherical(theta,phi,1.0f),float.max);
            bool v = !mScene.intersect(secRay,ints,true);
            if (v) {
                litCol += mEnvironment.getColor(theta,phi);
            }
        }
        litCol *= 1.0f/cast(float)SAMPLE_COUNT;
        col.r *= litCol.r;
        col.g *= litCol.g;
        col.b *= litCol.b;
    }

    public void environment(Environment env) {
        mEnvironment = env;
    }

    public char[] toString() {
        return "Sky";
    }
}

